home *** CD-ROM | disk | FTP | other *** search
/ PC go! 2008 April / PCgo 2008-04 (DVD).iso / interface / contents / demoversionen_3846 / 13664 / files / Data1.cab / roundedrect.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-10-16  |  16.3 KB  |  526 lines

  1. unit RoundedRect;
  2.  
  3. interface
  4.  
  5. uses
  6.   ComObj,
  7.   ActiveX,
  8.   RRect_TLB,
  9.   Forms,
  10.   PropPageF,
  11.   Windows,
  12.   SysUtils,
  13.   Controls;
  14.  
  15. type
  16.   TRoundedRect = class(TAutoObject, IRoundedRect)
  17.   protected
  18.   MyForm: TForm1; { Property Page form }
  19.  
  20.  // protected
  21.     function Draw(GrfThis, View, mat: OleVariant): WordBool; safecall;
  22.     function Get_ClassID: WideString; safecall;
  23.     function Get_Description: WideString; safecall;
  24.     function GetEnumNames(PropID: Integer; var Names,
  25.       Values: OleVariant): Integer; safecall;
  26.     function GetPageInfo(AGraphic: OleVariant; var StockPages: Integer;
  27.       var Names: OleVariant): Integer; safecall;
  28.     function GetPropertyInfo(var Names, Types, IDs,
  29.       Defaults: OleVariant): Integer; safecall;
  30.     function GetWizardInfo(var Names: OleVariant): Integer; safecall;
  31.     function OnCopyGraphic(grfCopy, grfSource: OleVariant): WordBool;
  32.       safecall;
  33.     function OnGeometryChanging(Graphic: OleVariant; GeomID: Integer;
  34.       ParamOld, ParamNew: OleVariant): WordBool; safecall;
  35.     function OnNewGraphic(grfThis: OleVariant; boolCopy: WordBool): WordBool;
  36.       safecall;
  37.     function OnPropertyChanging(Graphic: OleVariant; PropID: Integer;
  38.       ValueOld, ValueNew: OleVariant): WordBool; safecall;
  39.     function PageControls(ThisRegenMethod, Graphic: OleVariant;
  40.       PageNumber: Integer; SaveProperties: WordBool): WordBool; safecall;
  41.     function PropertyPages(ThisRegenMethod, PageNumber: OleVariant): WordBool;
  42.       safecall;
  43.     function Wizard(ThisRegenMethod, WizardNumber: OleVariant): WordBool;
  44.       safecall;
  45.     procedure OnGeometryChanged(Graphic: OleVariant; GeomID: Integer;
  46.       ParanOld, ParamNew: OleVariant); safecall;
  47.     procedure OnPropertyChanged(Graphic: OleVariant; PropID: Integer;
  48.       OldValue, NewValue: OleVariant); safecall;
  49.     procedure OnPropertyGet(Graphic: OleVariant; PropID: Integer); safecall;
  50.     procedure PageDone(ThisRegenMethod, PageNumber: OleVariant); safecall;
  51.     procedure Regen(grfThis: OleVariant); safecall;
  52.     { Protected declarations }
  53.   end;
  54. const
  55. { DBAPI constants }
  56.   gkGraphic = 11;
  57.   gkArc = 2;
  58.   gkText = 6;
  59.   gfCosmetic = 128;
  60.  
  61.  
  62. { Useful math constants }
  63.   Pi: double = 3.14159265;
  64. { Stock property pages }
  65.   ppStockPen = 1;
  66.   ppStockBrush = 2;
  67.   ppStockText = 4;
  68.   ppStockInsert = 8;
  69.   ppStockViewport = 16;
  70.   ppStockAuto = 32;
  71.  
  72. { Property Ids }
  73.   idRoundness = 1;
  74. { Number of properties, pages, wizards }
  75.   NUM_PROPERTIES = 1;
  76.   NUM_PAGES = 1;
  77.   NUM_WIZARDS = 0;
  78.  
  79. implementation
  80.  
  81. uses ComServ;
  82.  
  83. function TRoundedRect.Draw(GrfThis, View, mat: OleVariant): WordBool;
  84. begin
  85.     Result:=False;
  86. end;
  87.  
  88. function TRoundedRect.Get_ClassID: WideString;
  89. begin
  90.      Result:=GUIDtoString(CLASS_RoundedRect);
  91. end;
  92.  
  93. function TRoundedRect.Get_Description: WideString;
  94. begin
  95.      Result:='SDK Delphi v4 rounded rectangle';
  96. end;
  97.  
  98. function TRoundedRect.GetEnumNames(PropID: Integer; var Names,
  99.   Values: OleVariant): Integer;
  100. begin
  101.     Result := 0;
  102. end;
  103.  
  104. function TRoundedRect.GetPageInfo(AGraphic: OleVariant;
  105.   var StockPages: Integer; var Names: OleVariant): Integer;
  106. begin
  107.  
  108.    VarArrayRedim(Names, NUM_PAGES);
  109.  
  110.    { Need the form }
  111.  
  112.    MyForm := TForm1.Create(Application);
  113.    Names[0] := MyForm.Caption;
  114.    MyForm.Free;
  115.  
  116.    StockPages := ppStockBrush + ppStockPen + ppStockAuto;
  117.    Result := NUM_PAGES;
  118.  
  119. end;
  120.  
  121. function TRoundedRect.GetPropertyInfo(var Names, Types, IDs,
  122.   Defaults: OleVariant): Integer;
  123. begin
  124.     try
  125.       VarArrayRedim(Names, NUM_PROPERTIES);
  126.       VarArrayRedim(Types, NUM_PROPERTIES);
  127.       VarArrayRedim(IDs, NUM_PROPERTIES);
  128.       VarArrayRedim(Defaults, NUM_PROPERTIES);
  129.       Names[0] := 'Roundness';
  130.       Types[0] := varDouble;
  131.       IDs[0] := idRoundness;
  132.       Defaults[0] := 50.0;
  133.  
  134.       Result := NUM_PROPERTIES;
  135.  
  136.     except
  137.         Result := 0;
  138.     //  GetPropertyInfo := 0;
  139.    end;
  140.  
  141. end;
  142.  
  143. function TRoundedRect.GetWizardInfo(var Names: OleVariant): Integer;
  144. begin
  145.     Result := NUM_WIZARDS;
  146. end;
  147.  
  148. function TRoundedRect.OnCopyGraphic(grfCopy,
  149.   grfSource: OleVariant): WordBool;
  150. begin
  151.     Result := True;
  152. end;
  153.  
  154. function TRoundedRect.OnGeometryChanging(Graphic: OleVariant;
  155.   GeomID: Integer; ParamOld, ParamNew: OleVariant): WordBool;
  156. begin
  157.     Result := True;
  158. end;
  159.  
  160. function TRoundedRect.OnNewGraphic(grfThis: OleVariant;
  161.   boolCopy: WordBool): WordBool;
  162. var
  163.    R, Roundness, Offset: double;
  164.    Vertices, vTrue, vFalse: OleVariant;
  165.    X, Y, Z: double;
  166.   begin
  167. {  MessageBox ( NULL,'On new Graphic method','vv', IDOK);}
  168.     if boolCopy then
  169.     begin
  170.         { Vertices are already added for us... }
  171.         Result := True;
  172.         exit;
  173.     end;
  174.  
  175.     try
  176.         { New Graphic being created }
  177.         { Temporary veriable for Vertices.Add }
  178.         Vertices := grfThis.Vertices;
  179.  
  180.         { Define True and False variants }
  181.         vTrue := True;
  182.         vFalse := False;
  183.  
  184.         { First Vertex is "lower left" corner }
  185.         { Arguments for Vertices.Add are:
  186.         { X, Y, Z: double; }
  187.         { PenDown, Selectable, Snappable, Editable, Linkable, Calculated, }
  188.         { Before, After: OleVariant. }
  189.         { Specify all flags;  Omit Before and After arguments. }
  190.         X := -1.0;
  191.         Y := -0.5;
  192.         Z := 0.0;
  193.         Vertices.Add(X, Y, Z,
  194.             vFalse, vTrue, vFalse, vFalse, vFalse, vFalse, , );
  195.  
  196.         { Second Vertex is "upper right" corner }
  197.         X := 1.0;
  198.         Y := 0.5;
  199.         Vertices.Add(X, Y, Z,
  200.             vFalse, vTrue, vFalse, vFalse, vFalse, vFalse, , );
  201.  
  202.         { Third Vertex is rounding handle (calculated) }
  203.         Roundness := grfThis.Properties['Roundness'];
  204.         R := 0.5 * Roundness / 100.0;
  205.         Offset := 0.1 * R;
  206.         X := 1.0 - R;
  207.         Y := 0.5 + Offset;
  208.            Vertices.Add(X, Y, Z,
  209.             vFalse, vFalse, vFalse, vFalse, vFalse, vFalse, , );
  210.  
  211.         { Fourth Vertex is rounding handle (editable) }
  212.            Vertices.Add(X, Y, Z,
  213.             vFalse, vTrue, vFalse, vTrue, vFalse, vFalse, , );
  214.         OnNewGraphic := True;
  215.  //       Result := True;
  216.     except
  217.     { Return false on failure }
  218.        Result := False;
  219.     end;
  220.  
  221. end;
  222.  
  223. function TRoundedRect.OnPropertyChanging(Graphic: OleVariant;
  224.   PropID: Integer; ValueOld, ValueNew: OleVariant): WordBool;
  225. begin
  226.     Result:=True;
  227. end;
  228.  
  229. function TRoundedRect.PageControls(ThisRegenMethod, Graphic: OleVariant;
  230.   PageNumber: Integer; SaveProperties: WordBool): WordBool;
  231.  
  232. var
  233.    Roundness: double;
  234. begin
  235.      try
  236.         if SaveProperties then
  237.         begin
  238.             { OK button on property page was clicked }
  239.             { Form is still loaded }
  240.             with MyForm do
  241.             begin
  242.                 { Need try block for the case where you have }
  243.                 { TRoundedRect Turbo Shape and ahother "shape" selected }
  244.                 try
  245.                    { When the property page is closed, transfer the numeric }
  246.                    { roundness value from the EditBox to the Graphic }
  247.                    { Get the value as a double-precision number }
  248.                    Roundness := StrToFloat(txtRoundness.Text);
  249.  
  250.                    { Make sure it's between 0 and 100 }
  251.                    if Roundness < 0.0 then Roundness := 0.0;
  252.                    if Roundness > 100.0 then Roundness := 100.0;
  253.                    { Set the roundness property value in the Graphic }
  254.                    Graphic.Properties['Roundness'] := Roundness;
  255.                 except
  256.                 end;
  257.             end;
  258.         end
  259.         else
  260.         begin
  261.             { Property page is about to be opened }
  262.             { Make sure the form is loaded }
  263.             MyForm := TForm1.Create(Application);
  264.             with MyForm do
  265.             begin
  266.                 { If more than one TRoundedRect is selected and they do not }
  267.                 { have the same properties, don't set up this field }
  268.                 try
  269.  
  270.                     { When the property page is opening, transfer the numeric }
  271.                     { roundness value from the Graphic to the TextBox }
  272.                     { Get the roundness property value from the Graphic }
  273.                     Roundness := Graphic.Properties['Roundness'];
  274.                     { Set the EditBox control's text }
  275.                         txtRoundness.Text := FloatToStrF(Roundness, ffGeneral,
  276.                                    3, 0);
  277.                 except
  278.                 end;
  279.             end;
  280.         end;
  281.         Result:=True;
  282.  
  283.      except
  284.         { For debugging purposes, report that an error occurred }
  285.         { Return false if an error occurred }
  286.          Result := False;
  287.  
  288.      end;
  289. end;
  290.  
  291. function TRoundedRect.PropertyPages(ThisRegenMethod,
  292.   PageNumber: OleVariant): WordBool;
  293. var
  294.    PageResult: Integer;
  295. begin
  296.     with MyForm do
  297.     begin
  298.         PageResult := ShowModal;
  299.         Result := (PageResult = mrOk);
  300.     end;
  301. end;
  302.  
  303. function TRoundedRect.Wizard(ThisRegenMethod,
  304.   WizardNumber: OleVariant): WordBool;
  305. begin
  306.      Result := False;
  307. end;
  308.  
  309. procedure TRoundedRect.OnGeometryChanged(Graphic: OleVariant;
  310.   GeomID: Integer; ParanOld, ParamNew: OleVariant);
  311. begin
  312.  
  313. end;
  314.  
  315. procedure TRoundedRect.OnPropertyChanged(Graphic: OleVariant;
  316.   PropID: Integer; OldValue, NewValue: OleVariant);
  317. begin
  318.  
  319. end;
  320.  
  321. procedure TRoundedRect.OnPropertyGet(Graphic: OleVariant;
  322.   PropID: Integer);
  323. begin
  324.  
  325. end;
  326.  
  327. procedure TRoundedRect.PageDone(ThisRegenMethod, PageNumber: OleVariant);
  328. begin
  329.         MyForm.Free;
  330. end;
  331.  
  332. procedure TRoundedRect.Regen(grfThis: OleVariant);
  333. var
  334.     LockCount: Integer;
  335.     boolHandleMoved: WordBool;
  336.     W, H, R, Roundness: double;
  337.     X, Y, Z, X0, Y0, X1, Y1, T, StartAngle, EndAngle: double;
  338.         Props, propRoundness: OleVariant;
  339.         grfChild, Vertices, V0, V1, V2, V3, vTrue, vFalse: OleVariant;
  340. begin
  341.   //MessageBox ( NULL,'On Regen method','vv', IDOK);
  342.   { Setup error handler }
  343.   try
  344.      { grfThis.Application.PushVertexDefaults Editable:=True, Selectable:=True }
  345.  
  346.      { Set up lock (prevent recursion) }
  347.      LockCount := grfThis.RegenLock;
  348.  
  349.      { Setup error handler (make sure lock is removed) }
  350.      if LockCount = 0 then
  351.      begin
  352.          try
  353.             { Delete any previous cosmetic children }
  354.             grfThis.Graphics.Clear(gfCosmetic);
  355.  
  356.             { Calculate height, width and radius of corners }
  357.             Vertices := grfThis.Vertices;
  358.             V0 := Vertices.Item[0]; { First corner }
  359.             V1 := Vertices.Item[1]; { Diagonal corner }
  360.             V2 := Vertices.Item[2]; { Radius }
  361.             V3 := Vertices.Item[3]; { Drag handle }
  362.  
  363.             if (Abs(V2.X - V3.X) < 0.000001) and
  364.                (Abs(V2.Y - V3.Y) < 0.000001) then boolHandleMoved := False
  365.             else boolHandleMoved := True;
  366.  
  367.             W := Abs(V1.X - V0.X);
  368.             H := Abs(V1.Y - V0.Y);
  369.  
  370.             { Radius of arcs is based on minimum of width and height }
  371.             if W < H then R := W / 2.0
  372.             else R := H / 2.0;
  373.  
  374.             { Adjust radius for roundness }
  375.             Props := grfThis.Properties;
  376.             propRoundness := Props.Item['Roundness'];
  377.             if boolHandleMoved then
  378.             begin
  379.                 Roundness := Abs(V2.X - V3.X);
  380.                 Roundness := Roundness * 100.0 / R;
  381.                 if Roundness > 100.0 then Roundness := 100.0;
  382.                 { Relocate handle }
  383.  
  384.                 { Update property to reflect handle location }
  385.                 propRoundness.Value := Roundness;
  386.             end
  387.             else
  388.             begin
  389.                 Roundness := propRoundness.Value;
  390.                 if Roundness < 0.0 then Roundness := 0.0;
  391.                 if Roundness > 100.0 then Roundness := 100.0;
  392.             end;
  393.             R := R * Roundness / 100.0;
  394.  
  395.             { Add child Graphics }
  396.             X0 := V0.X;
  397.             Y0 := V0.Y;
  398.             X1 := V1.X;
  399.             Y1 := V1.Y;
  400.             { Make sure X0 < X1 }
  401.             if X0 > X1 then
  402.             begin
  403.                 T := X0;
  404.                 X0 := X1;
  405.                 X1 := T;
  406.             end;
  407.             { Make sure Y0 < Y1 }
  408.             if Y0 > Y1 then
  409.             begin
  410.                 T := Y0;
  411.                 Y0 := Y1;
  412.                 Y1 := T;
  413.             end;
  414.  
  415.             vTrue := True;
  416.             vFalse := False;
  417.             if R = 0 then
  418.             begin
  419.                 { No rounded corners }
  420.                 { All children are cosmetic }
  421.                 grfChild := grfThis.Graphics.Add( , , vTrue, , , );
  422.                 grfChild.Cosmetic := True;
  423.                 { Now add vertices to the child }
  424.                 Vertices := grfChild.Vertices;
  425.                 X := X0;
  426.                 Y := Y0;
  427.                 Z := 0.0;
  428.                 Vertices.Add(X, Y, Z, , , , , , , , );
  429.                 Y := Y1;
  430.                 Vertices.Add(X, Y, Z, vTrue, , , , , , , );
  431.                 X := X1;
  432.                 Vertices.Add(X, Y, Z, vTrue, , , , , , , );
  433.                 Y := Y0;
  434.                 Vertices.Add(X, Y, Z, vTrue, , , , , , , );
  435.                 { Close the rectangle }
  436.                 Vertices.AddClose(vTrue, , , , , );
  437.             end
  438.             else
  439.             begin
  440.                 { Rounded corners }
  441.                 { We'll make 4 line children and 4 arc children }
  442.                 { First line }
  443.                 { All children are cosmetic }
  444.                 grfChild := grfThis.Graphics.Add( , , vTrue, , , );
  445.                 grfChild.Cosmetic := True;
  446.                 { Now add vertices to the child }
  447.                 Vertices := grfChild.Vertices;
  448.                 X := X0 + R;
  449.                 Y := Y0;
  450.                 Z := 0;
  451.                 Vertices.Add(X, Y, Z, , , , , , , , );
  452.                 X := X1 - R;
  453.                 Vertices.Add(X, Y, Z, vTrue, , , , , , , );
  454.                 { First arc }
  455.                 grfChild := grfThis.Graphics.Add(gkArc, , vTrue, , , );
  456.                 grfChild.Cosmetic := True;
  457.                 Y := Y0 + R;
  458.                 StartAngle := 1.5 * Pi;
  459.                 EndAngle := 0.0;
  460.                 grfChild.ArcSet(X, Y, Z, R, , StartAngle, EndAngle, );
  461.                 { Second line }
  462.                 grfChild := grfThis.Graphics.Add( , , vTrue, , , );
  463.                 grfChild.Cosmetic := True;
  464.                 Vertices := grfChild.Vertices;
  465.                 X := X1;
  466.                 Vertices.Add(X, Y, Z, , , , , , , , );
  467.                 Y := Y1 - R;
  468.                 Vertices.Add(X, Y, Z, vTrue, , , , , , , );
  469.                 { Second arc }
  470.                 grfChild := grfThis.Graphics.Add(gkArc, , vTrue, , , );
  471.                 grfChild.Cosmetic := True;
  472.                 X := X1 - R;
  473.                 StartAngle := 0.0;
  474.                 EndAngle := 0.5 * Pi;
  475.                 grfChild.ArcSet(X, Y, Z, R, , StartAngle, EndAngle, );
  476.                 { Third line }
  477.                 grfChild := grfThis.Graphics.Add( , , vTrue, , , );
  478.                 grfChild.Cosmetic := True;
  479.                 Vertices := grfChild.Vertices;
  480.                 Y := Y1;
  481.                 Vertices.Add(X, Y, Z, , , , , , , , );
  482.                 X := X0 + R;
  483.                 Vertices.Add(X, Y, Z, vTrue, , , , , , , );
  484.                 { Third arc }
  485.                 grfChild := grfThis.Graphics.Add(gkArc, , vTrue, , , );
  486.                 grfChild.Cosmetic := True;
  487.                 Y := Y1 - R;
  488.                 StartAngle := 0.5 * Pi;
  489.                 EndAngle := Pi;
  490.                 grfChild.ArcSet(X, Y, Z, R, , StartAngle, EndAngle, );
  491.                 { Fourth line }
  492.                 grfChild := grfThis.Graphics.Add( , , vTrue, , , );
  493.                 grfChild.Cosmetic := True;
  494.                 Vertices := grfChild.Vertices;
  495.                 X := X0;
  496.                 Vertices.Add(X, Y, Z, , , , , , , , );
  497.                 Y := Y0 + R;
  498.                 Vertices.Add(X, Y, Z, vTrue, , , , , , , );
  499.                 { Fourth arc }
  500.                 grfChild := grfThis.Graphics.Add(gkArc, , vTrue, , , );
  501.                 grfChild.Cosmetic := True;
  502.                 X := X0 + R;
  503.                 StartAngle := Pi;
  504.                 EndAngle := 1.5 * Pi;
  505.                 grfChild.ArcSet(X, Y, Z, R, , StartAngle, EndAngle, );
  506.             end;
  507.  
  508.             { Add visible child Graphics }
  509.  
  510.          except
  511.          end;
  512.      end; { if LockCount = 0 }
  513.  
  514.      { Remove lock }
  515.      grfThis.RegenUnlock;
  516.      { grfThis.Application.PopVertexDefaults }
  517.   except
  518.   end;
  519.  
  520. end;
  521.  
  522. initialization
  523.   TAutoObjectFactory.Create(ComServer, TRoundedRect, Class_RoundedRect,
  524.     ciMultiInstance, tmApartment);
  525. end.
  526.